#ifndef __ENCODER_H__
#define __ENCODER_H__

#include "stdio.h"
#include "stdint.h"
#include "vencoder.h"
#include <sys/time.h>
#include <memoryAdapter.h>
#include "rtsp.h"
#define ALIGN_XXB(y, x) (((x) + ((y)-1)) & ~((y)-1))

struct VidEncOutputBuf
{
    bool key_flag;  //1->IFrame, 0->PFrame
    int32_t pts;

    uint8_t *spspps_data;
    int32_t spspps_data_size;

    uint8_t *data;
    int32_t data_size;
};



typedef int32_t (*VidEncoderCallback)( VidEncOutputBuf *buffer, void *ctx );

struct CoderConfig
{
    int32_t width;
    int32_t height;
    int32_t fps;
    int32_t bitrate;
};


class IVidEncoder
{
private:

public:
    IVidEncoder(){};
    virtual ~IVidEncoder(){};

    virtual int32_t Start(CoderConfig config) = 0;
    virtual int32_t Stop() = 0;

    virtual int32_t Deliver(struct MemoryFrame *frame) = 0;
    virtual int32_t Regcb(VidEncoderCallback callbcak, void *ctx) = 0;
};


class H264Encoder : public AWRtspStream, public IVidEncoder
{
private:
    VidEncoderCallback _enc_callbcak;
    void* _enc_callbcak_ctx;
    bool _isStart;

    VencBaseConfig _venc_base_config;
    VideoEncoder *_venc_handle;
    VencH264Param _venc_h264_param;
    VencAllocateBufferParam _venc_h264_buf_param;

    CoderConfig _coder_config;

public:
    H264Encoder();
    virtual ~H264Encoder();

    virtual int32_t Start( CoderConfig config );
    virtual int32_t Stop();

    virtual int32_t Deliver(struct MemoryFrame *frame);
    virtual int32_t Regcb(VidEncoderCallback callbcak, void *ctx);
};

#ifdef __cplusplus
extern "C" {
#endif

typedef void *AW_VID_ENCODER_HANDLE;

typedef struct aw_vid_enc_instance {
    CoderConfig codec_cfg;
    IVidEncoder *IVidEnc;
}vid_enc_ins;


int32_t aw_vid_enc_init( CoderConfig codec_config, /*out*/AW_VID_ENCODER_HANDLE *handle );
int32_t aw_vid_enc_deinit( /*in*/AW_VID_ENCODER_HANDLE handle );

int32_t aw_vid_enc_start( /*in*/AW_VID_ENCODER_HANDLE handle );
int32_t aw_vid_enc_stop( /*in*/AW_VID_ENCODER_HANDLE handle );

int32_t aw_vid_enc_regcb( /*in*/AW_VID_ENCODER_HANDLE handle, VidEncoderCallback enc_cb, void *ctx );
int32_t aw_vid_enc_deliver( /*in*/AW_VID_ENCODER_HANDLE handle, struct MemoryFrame *frame );


#ifdef __cplusplus
}
#endif


#endif